package com.changgou.seckill.timer;

import com.changgou.seckill.dao.SeckillGoodsMapper;
import com.changgou.seckill.pojo.SeckillGoods;
import com.changgou.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Set;

/*****
 * @Author: 黑马训练营
 * @Description: com.changgou.seckill.timer
 ****/
@Component
public class SeckillGoodsPushTask {

    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    /***
     * 定时任务
     * @Scheduled(cron = "0/10 * * * * ?"): 从0秒开始执行，每过10秒再执行一次
     */
    @Scheduled(cron = "0/10 * * * * ?")
    //@Scheduled(cron = "3,5,6,8,10,12 * * * * ?")
    //@Scheduled(cron = "0-10 * * * * ?")  从0秒开始执行，执行到第10秒
    public void loadGoodsPushRedis(){
        //1.首先计算5个时间段   List<Date> times
        List<Date> dateMenus = DateUtil.getDateMenus();

        //2.循环times，根据循环的时间价值对应时间范围的数据
        for (Date dateMenu : dateMenus) {
            //SeckollGoods_2020010610
            String key = "SeckillGoods_"+DateUtil.data2str(dateMenu,DateUtil.PATTERN_YYYYMMDDHH);
            //手动拼接条件  Example
            Example example = new Example(SeckillGoods.class);
            Example.Criteria criteria = example.createCriteria();

            //商品审核通过
            criteria.andEqualTo("status","1");

            //库存>0
            criteria.andGreaterThan("stockCount",0);

            //加载查询当前时间区间的商品数据
            //   starttime>=dateMenu[开始时间]
            //   endtime< dateMenu+2h
            criteria.andGreaterThanOrEqualTo("startTime",dateMenu);
            criteria.andLessThan("endTime",DateUtil.addDateHour(dateMenu,2));

            //Redis中如果有该商品的缓存，则不需要加载
            //查询当前key对应的所有商品的id(keys)
            // select * from table where id not in(1,23,5,6)
            Set<String> keys = redisTemplate.boundHashOps(key).keys();
            if(keys!=null && keys.size()>0){
                criteria.andNotIn("id",keys);
            }

            //查询
            List<SeckillGoods> seckillGoods = seckillGoodsMapper.selectByExample(example);

            //3.将对应时间范围的数据存入到Redis缓存
            for (SeckillGoods seckillGood : seckillGoods) {
                redisTemplate.boundHashOps(key).put(seckillGood.getId(),seckillGood);

                //将商品的个数信息存入到队列中  key value   .leftPush():从队列的左边存入数据
                redisTemplate.boundListOps("SeckillGoodsCountList_"+seckillGood.getId()).leftPushAll(pushIds(seckillGood.getStockCount(),seckillGood.getId()));

                //商品库存计数器
                redisTemplate.boundHashOps("SeckillGoodsCount").increment(seckillGood.getId(),seckillGood.getStockCount());
            }
        }
    }

    /****
     * 获取商品库存数量对应的数组
     * count:库存数量
     * id:商品ID
     */
    public String[] pushIds(int count,String id){
        String[] ids = new String[count];
        for (int i = 0; i <count ; i++) {
            ids[i]=id;
        }
        return ids;
    }

}
